package d512a.TAKO;


public class FoodRating {

	private static int fatScore;
	private static int proteinScore;
	private static int carbonHydrateScore;

	public static int calculateRating(float fat, float saturatedFat, float monoUnsaturatedFat,
			float polyUnsaturatedFat, float protein, float carbonHydrate, float sugar) {
		fatScore = calculateFatScore(fat, saturatedFat, monoUnsaturatedFat, polyUnsaturatedFat);
		proteinScore = calculateProteinScore(protein);
		carbonHydrateScore = calculateCarbonHydrateScore(carbonHydrate, sugar);
		return (int) ((fatScore + proteinScore + carbonHydrateScore) / 3);
	}

	private static int calculateFatScore(float fat, float saturatedFat, float monoUnsaturatedFat,
			float polyUnsaturatedFat) {
		fatScore = 100;
		int saturatedFatScore = 100;
		int monoUnsaturatedFatScore = 100;
		int polyUnsaturatedFatScore = 100;
		int maxFat = 30;
		int maxSaturated = 10; // m�ttede fedtsyrer

		fatScore = rateProduct(100, maxFat, fat);

		saturatedFatScore = rateProduct(saturatedFatScore, maxSaturated, saturatedFat);

		// Check if monoUnsaturatedFat is within 10-15%
		int lowerBorder = 10;
		int upperBorder = 15;
		float upperIntervals = 8.5f;

		if (monoUnsaturatedFat < lowerBorder) {
			// Since lowerIntervals = 1 then we can just use ceiling on protein
			// and multiply with 10
			int currentInterval = (int) Math.floor(monoUnsaturatedFat);
			switch (currentInterval) {
			case 9:
			case 8:
				monoUnsaturatedFatScore = (currentInterval == 9 ? 95 : 90);
				break;
			case 7:
			case 6:
				monoUnsaturatedFatScore = (currentInterval == 7 ? 85 : 75);
				break;
			case 5:
			case 4:
				monoUnsaturatedFatScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 3:
			case 2:
				monoUnsaturatedFatScore = (currentInterval == 3 ? 45 : 30);
				break;
			case 1:
			case 0:
				monoUnsaturatedFatScore = (currentInterval == 1 ? 15 : 0);
				break;
			default:
				break;
			}
		} else if (monoUnsaturatedFat > upperBorder) {
			int currentInterval = (int) Math.ceil((monoUnsaturatedFat - upperBorder)
					/ upperIntervals);
			switch (currentInterval) {
			case 1:
			case 2:
				monoUnsaturatedFatScore = (currentInterval == 1 ? 95 : 90);
				break;
			case 3:
			case 4:
				monoUnsaturatedFatScore = (currentInterval == 3 ? 85 : 75);
				break;
			case 5:
			case 6:
				monoUnsaturatedFatScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 7:
			case 8:
				monoUnsaturatedFatScore = (currentInterval == 7 ? 45 : 30);
				break;
			case 9:
			case 10:
				monoUnsaturatedFatScore = (currentInterval == 9 ? 15 : 0);
				break;
			default:
				break;
			}
		}

		lowerBorder = 5;
		upperBorder = 10;
		float lowerIntervals = 0.5f;
		upperIntervals = 9f;

		if (polyUnsaturatedFat < lowerBorder) {
			int currentInterval = (int) Math.floor((lowerBorder - polyUnsaturatedFat)
					/ lowerIntervals);
			switch (currentInterval) {
			case 9:
            case 8:
                polyUnsaturatedFatScore = (currentInterval == 9 ? 95 : 90);
                break;
            case 7:
            case 6:
                polyUnsaturatedFatScore = (currentInterval == 7 ? 85 : 75);
                break;
            case 5:
            case 4:
                polyUnsaturatedFatScore = (currentInterval == 5 ? 65 : 55);
                break;
            case 3:
            case 2:
                polyUnsaturatedFatScore = (currentInterval == 3 ? 45 : 30);
                break;
            case 1:
            case 0:
                polyUnsaturatedFatScore = (currentInterval == 1 ? 15 : 0);
                break;
            default:
                break;
			}
		} else if (polyUnsaturatedFat > upperBorder) {
			int currentInterval = (int) Math.ceil((polyUnsaturatedFat - upperBorder)
					/ upperIntervals);
			switch (currentInterval) {
			case 1:
			case 2:
				polyUnsaturatedFatScore = (currentInterval == 1 ? 95 : 90);
				break;
			case 3:
			case 4:
				polyUnsaturatedFatScore = (currentInterval == 3 ? 85 : 75);
				break;
			case 5:
			case 6:
				polyUnsaturatedFatScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 7:
			case 8:
				polyUnsaturatedFatScore = (currentInterval == 7 ? 45 : 30);
				break;
			case 9:
			case 10:
				polyUnsaturatedFatScore = (currentInterval == 9 ? 15 : 0);
				break;
			default:
				break;
			}
		}
		return (int) ((fatScore + saturatedFatScore + monoUnsaturatedFatScore + polyUnsaturatedFatScore) / 4);
	}

	private static int calculateProteinScore(float protein) {
		proteinScore = 100;
		int lowerBorder = 10;
		int upperBorder = 20;
		int upperIntervals = 8;

		if (protein < lowerBorder) {
			int currentInterval = (int) Math.floor(protein);
			switch (currentInterval) {
			case 9:
			case 8:
				proteinScore = (currentInterval == 9 ? 95 : 90);
				break;
			case 7:
			case 6:
				proteinScore = (currentInterval == 7 ? 85 : 75);
				break;
			case 5:
			case 4:
				proteinScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 3:
			case 2:
				proteinScore = (currentInterval == 3 ? 45 : 30);
				break;
			case 1:
			case 0:
				proteinScore = (currentInterval == 1 ? 15 : 0);
				break;
			default:
				break;
			}
		} else if (protein > upperBorder) {
			int currentInterval = (int) Math.ceil((protein - upperBorder) / upperIntervals);
			switch (currentInterval) {
			case 1:
			case 2:
				proteinScore = (currentInterval == 1 ? 95 : 90);
				break;
			case 3:
			case 4:
				proteinScore = (currentInterval == 3 ? 85 : 75);
				break;
			case 5:
			case 6:
				proteinScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 7:
			case 8:
				proteinScore = (currentInterval == 7 ? 45 : 30);
				break;
			case 9:
			case 10:
				proteinScore = (currentInterval == 9 ? 15 : 0);
				break;
			default:
				break;
			}
		}
		return proteinScore;
	}

	private static int calculateCarbonHydrateScore(float carbonHydrate, float sugar) {
		carbonHydrateScore = 100;
		int sugarScore = 100;
		int lowerBorder = 50;
		int upperBorder = 60;
		int lowerIntervals = 5;
		int upperIntervals = 4;
		int maxSugar = 1;

		if (carbonHydrate < lowerBorder) {
			int currentInterval = (int) Math.floor((lowerBorder - carbonHydrate) / lowerIntervals);
			switch (currentInterval) {
			case 9:
			case 8:
				carbonHydrateScore = (currentInterval == 9 ? 95 : 90);
				break;
			case 7:
			case 6:
				carbonHydrateScore = (currentInterval == 7 ? 85 : 75);
				break;
			case 5:
			case 4:
				carbonHydrateScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 3:
			case 2:
				carbonHydrateScore = (currentInterval == 3 ? 45 : 30);
				break;
			case 1:
			case 0:
				carbonHydrateScore = (currentInterval == 1 ? 15 : 0);
				break;
			default:
				break;
			}
		} else if (carbonHydrate > upperBorder) {
			int currentInterval = (int) Math.ceil((carbonHydrate - upperBorder) / upperIntervals);
			switch (currentInterval) {
			case 1:
			case 2:
				carbonHydrateScore = (currentInterval == 1 ? 95 : 90);
				break;
			case 3:
			case 4:
				carbonHydrateScore = (currentInterval == 3 ? 85 : 75);
				break;
			case 5:
			case 6:
				carbonHydrateScore = (currentInterval == 5 ? 65 : 55);
				break;
			case 7:
			case 8:
				carbonHydrateScore = (currentInterval == 7 ? 45 : 30);
				break;
			case 9:
			case 10:
				carbonHydrateScore = (currentInterval == 9 ? 15 : 0);
				break;
			default:
				break;
			}
		}

		return (int) ((carbonHydrateScore + rateProduct(sugarScore, maxSugar, sugar)) / 2);
	}

	private static int rateProduct(int maxScore, int maxAllowedAmount, float amount) {
		int interval = (100 - maxAllowedAmount) / 10;

		if (amount < maxAllowedAmount) {
			maxScore = 100;
		} else if (amount == maxAllowedAmount) {
			maxScore = 95;
		} else {
			int currentInterval = (int) (Math.ceil(amount - maxAllowedAmount) / interval);

			switch (currentInterval) {
			case 1:
			case 2:
				maxScore = (interval == 1 ? 95 : 90);
				break;
			case 3:
			case 4:
				maxScore = (interval == 3 ? 85 : 75);
				break;
			case 5:
			case 6:
				maxScore = (interval == 5 ? 65 : 55);
				break;
			case 7:
			case 8:
				maxScore = (interval == 7 ? 45 : 30);
				break;
			case 9:
			case 10:
				maxScore = (interval == 9 ? 15 : 0);
				break;
			default:
				break;
			}
		}
		return maxScore;
	}
}
